/* vim: set sw=8 ts=8 sts=8 expandtab: */
#include "Cmaid.h"
#include "cmaid_private.h"
#include <stdlib.h>
#include <stdio.h>

static void  cmaid_iter_empty_start(Cmaid_Iter *it);
static void *cmaid_iter_empty_iter_goto(Cmaid_Iter *it, const Cmaid_Iter *to);
static void *cmaid_iter_empty_index_goto(Cmaid_Iter *it, int index);
static void *cmaid_iter_empty_goto(Cmaid_Iter *it, const void *data);
static void *cmaid_iter_empty_current(Cmaid_Iter *it);

void
cmaid_iterlist_remove(Cmaid_Iter **iter, Cmaid_Iter *it)
{
        /* that should not happen */
        if (!*iter)
                return;

        /* remove from the iter list */        
        while ((*iter) != it)
        {
                /* seems it is not in the list */
                if (!(*iter)->next)
                        return;
                iter = &((*iter)->next);
        }
        *iter = (*iter)->next;
}

void
cmaid_iterlist_repair(Cmaid_Iter *iter, void *old_node, void *new_node)
{
        Cmaid_Iter *it;

        for (it = iter; it; it = it->next)
        {
                if (it->current == old_node)
                        it->current = new_node;
        }
}

/*
 * The interface of the empty iterator
 */
const Cmaid_Iter_Interface cmaid_iter_empty_if =
{
        cmaid_iter_empty_start,
        cmaid_iter_empty_iter_goto,
        cmaid_iter_empty_index_goto,
        cmaid_iter_empty_goto,
        cmaid_iter_empty_current,
        cmaid_iter_empty_current,
        cmaid_iter_empty_current,
        cmaid_iter_empty_start
};

/**
 * @param iter the iterator to attach
 * @return Returns no value
 * @brief Attach an iterator to an empty container
 *
 * This function attachs the given iterator to an empty container. All
 * iterator function calls are safe and do not have any side effects.
 * All interface functions with a return value are returning  @c NULL.
 */
void
cmaid_iter_empty_attach(Cmaid_Iter *iter)
{
        if (!iter)
                return;

        iter->interface = &cmaid_iter_empty_if;
        iter->index = -1;
}

/**
 * @param iter the iterator to detach
 * @return Returns @c TRUE if the given iterator was attached before with
 *         cmaid_iter_empty_attach() else @c FAlSE.
 * @brief Detach an iterator from the empty container
 *
 * This function will detach the iterator from the empty container. If
 * it was not attached before with cmaid_iter_empty_attach() the return value
 * will be @c FALSE.
 */
unsigned int
cmaid_iter_empty_detach(Cmaid_Iter *iter)
{
        if (iter && iter->interface == &cmaid_iter_empty_if)
        {
                memset(iter, 0, sizeof(*iter));
                return TRUE;
        }
        return FALSE;
}

static void
cmaid_iter_empty_start(Cmaid_Iter *it)
{
        (void)it;
}

static void *
cmaid_iter_empty_iter_goto(Cmaid_Iter *it, const Cmaid_Iter *to)
{
        (void)it;
        (void)to;
        return NULL;
}

static void *
cmaid_iter_empty_index_goto(Cmaid_Iter *it, int index)
{
        (void)it;
        (void)index;
        return NULL;
}

static void *
cmaid_iter_empty_goto(Cmaid_Iter *it, const void *data)
{
        (void)it;
        (void)data;
        return NULL;
}

static void *
cmaid_iter_empty_current(Cmaid_Iter *it)
{
        (void)it;
        return NULL;
}
